/**
 * 通过vjosn生成 api处理方案
 * @author xiufu.wang
 */

import deepmerge from 'deepmerge';
import Base from './Base'
class AbstractGenerateVjson extends Base{
    constructor(datas, options) {
        super()
        this.datas = deepmerge([], (datas || []))
        this.options = options || {}
    }
    get childrenField() {
        return this.options.childrenField || 'children'
    }

    updateData(datas) {
        this.datas = deepmerge([], datas || [])
    }

    appendDatas(datas){
        const _ndatas = deepmerge([], datas || [])
        this.datas = this.datas.concat(_ndatas)
    }

    generate() {
        const vjson = {}
        vjson.name = this.onHookName()
        vjson.classes = this.onHookClasses()
        vjson.styles = this.onHookStyles()
        vjson.datas = this.onHookDatas()
        vjson.props = this.onHookProps()
        vjson.watchs = this.onHookWatchs()
        vjson.methods = this.onHookMethods()
        vjson.dataSources = this.onHookDataSources()
        vjson.templates = this._generateTemplates()
        return vjson
    }
    /**
     * 抽象方法: 处理name
     */
    onHookName() { }
    /**
     * 抽象方法: 处理vnode class
     */
    onHookClasses() { }
    /**
    * 抽象方法: 处理vnode style
    */
    onHookStyles() { }
    /**
    * 抽象方法: 处理vnode data状态
    */
    onHookDatas() { }
    /**
     * 抽象方法: 处理vnode props
     */
    onHookProps() { }
    /**
    * 抽象方法: 处理vnode watch
    */
    onHookWatchs() { }
    /**
    * 抽象方法: 处理vnode methods
    */
    onHookMethods() { }
    /**
    * 抽象方法: 处理vnode datasource mixins
    */
    onHookDataSources() { }

    /**
     * 抽象方法: vnode节点包裹处理, 给vjson渲染的节点增加 特殊业务功能时,可以使用该hook防范,例如节点删除、排序、配置
     */
    onHookVnodeWapper() { }

    /**
     * 抽象方法: 处理vnode 根节点
     * @return vnode
     */

    onHookRootWapper() {
        const vnode = {
            tag: 'el-form',
            props: {
                ':model': 'form'
            },
            slots: {
                default: []
            }
        }
        return (childrenVnodes) => {
            vnode.slots.default = Array.isArray(childrenVnodes) ? childrenVnodes : [childrenVnodes]
            return vnode
        }
    }
    /**
   * 抽象方法: 创建vnode data
   */
    onHookTemplateVnode(row) { }
    /**
     * 抽象方法: 处理vnode
     * @return vnode
     */
    onHookTemplates(vnodeJsons, datas) {
        datas = datas || []
        const childrenField = this.childrenField
        for (let i = 0; i < datas.length; i++) {
            const row = datas[i];
            const _vdata = this.onHookTemplateVnode(row)
            if (!_vdata) {
                continue
            }
            vnodeJsons.push(_vdata)
            //如果包含子节点
            if (row[childrenField]) {
                let childrens = row[childrenField] || []
                _vdata.slots.default = this.onHookTemplates([], Array.isArray(childrens) ? childrens : [childrens])
            }
        }
        return vnodeJsons
    }

    _generateTemplates() {
        const rootWapper = this.onHookRootWapper()
        const vjsonTpl = this.onHookTemplates([], this.datas)

        if (typeof rootWapper === 'function') {
            return rootWapper(vjsonTpl)
        }
        return vjsonTpl
    }
}

export default AbstractGenerateVjson